package fr.ece.ing4.si.singlethreadedmontecarlo;

import java.util.Random;

public class MonteCarloSimulation {
	
	private static final String CallPutFlag = "c"; // The option is a call
	private static final int S = 40; // Underlying asset actual price
	private static final int X = 50; // Strike price
	private static final double r = 0.06; // Basic interest rate (6%)
	private static final double T = 0.5; // Time remaining until the maturity of the option -> 6 months
	private static final double b = 0.10; // Detention costs rate of the option (10%)
	private static final double v = 0.45; // Volatility (45%)
	private static final int nSteps = 168;
	private static final int nSimulations = 100000;
	
	
	public double monteCarloStandardOption(String CallPutFlag, int S, int X, double r, double T, double b, double v, int nSteps, int nSimulations) {
		
		double dt = 0, St = 0;
		double Sum = 0, Drift = 0, vSqrdt = 0, optionPrice = 0;
		int z = 0;
		Random rand = new Random();
		
		dt = T / nSteps;
		Drift = (b - Math.pow(v,2) / 2) * dt;
		vSqrdt = v * Math.sqrt(dt);
		
		if(CallPutFlag.equals("c")) z = 1;
		else if(CallPutFlag.equals("p")) z = -1;
		
		for(int i=0 ; i<nSimulations ; i++) {
			St = S;
			
			for(int j=0 ; j<nSteps ; j++) {
				St = St * Math.exp(Drift + vSqrdt * rand.nextGaussian());
			}
			
			Sum = Sum + Math.max(z * (St - X), 0);
		}		
		
		optionPrice = Math.exp(-r * T) * (Sum / nSimulations);
		
		return optionPrice;
	}
	
}
